import logging
from runtime.nodelogger import NodeLogger
from datastore.resource import *
from datastore.uri import *
from runtime.service import *
from spear.a2p_service import A2PServiceAPI
import adaptor

class ApplicationService(Service):
    """
    
    """
    SPEAR_APPLICATION_HEADER = 'SPEAR Application'
    DOC_TYPES_TO_DISPLAY = [adaptor.DOC_TYPE_APPLICATION_FOR_PLANNING_PERMIT,
                            adaptor.DOC_TYPE_ACCEPT_REJECT,
                            adaptor.DOC_TYPE_REFERRAL_REQUEST,
                            adaptor.DOC_TYPE_RESPONSIBLE_AUTHORITY_REF_NUM]
    
    def cb_start(self, uri, action, res):
        self.spaces.set_process(Uri('internal:adaptor/application/'),self.cb_get_application)

    def cb_get_application(self, uri, action, res):
        if uri.split()[-1] == 'response':
            # we are not doing anything with the response so we can safely ignore it. 
            return         
        if action == Spaces.ACTION_EXISTS :
            return False
        elif action == Spaces.ACTION_PUT:
            self.logger.log(logging.DEBUG, "Requesting SPEAR Application")
            
            response = Resource(type='term:eplanning/adaptor/application/data')
            response.dc_title("SPEAR Application")
            response.dc_description("SPEAR Application")

            query_data = res.query_data
            spear_ref_no = query_data['spearRef']

            resource = self.spaces.get(Uri("spear:app/%s" % spear_ref_no))
            # if app doesn't exists
            if resource is None:
                response = Resource(type='term:eplanning/adaptor/error')
                response.h1_header = adaptor.ERROR_H1_HEADER
                response.error = adaptor.APP_NOT_FOUND_MSG % spear_ref_no
            # if app exists
            else:
                if resource.has_var('application'):
                    response.application = resource.application
                # sometimes we will retreieve a application which has not yet created the applicaiton
                # attribute in the resource. We will create one now and put in the minimal data required 
                # in it.
                else:
                    response.application = {}
                    # Only the SPEAR_Reference_Number is required right now
                    response.application['SPEAR_Reference_Number'] = resource.get_metadata(Uri('spearReferenceNumber'))
                response.applicant_docs = []
                response.council_docs = []
                response.referral_authority_docs = []
                response.objector_docs = []
                role_to_list = {'Applicant Contact':response.applicant_docs,
                                'Responsible Authority':response.council_docs,
                                'Referral Authority':response.referral_authority_docs,
                                'Online Objector':response.objector_docs}
                
                # sorting out which documents should be displayed according to SID102.A
                # check that sid004_dict exists and that it has the attachment dictionary list.
                # Also check the sid005a_dict_dict exists.
                if resource.has_var('sid004_dict') and 'sid004_attachment_dict_list' in resource.sid004_dict and resource.has_var('sid005a_dict_dict'):
                    # go through each document
                    for document in resource.sid004_dict['sid004_attachment_dict_list']:
                        if self._is_display_document(document, resource, self.spaces):
                            # we need to know who this document belongs to and place them in the appropriate list.
                            if document.has_key('sid004_owner_type__derived'):
                                role_to_list[document['sid004_owner_type__derived']].append(document)
                            else:
                                self.logger.log(logging.DEBUG, "%s ignored" % document['sid004_doctype'])
                        else:
                            self.logger.log(logging.DEBUG, "%s ignored" % document['sid004_doctype'])
                            
                response.control = resource.control_dict
                response.summary = resource.sid002b_dict
                
                response.h1_header = ApplicationService.SPEAR_APPLICATION_HEADER
            
            # Our response will go to the request uri + 'response'
            response_uri = uri + 'response'
                                    
            self.spaces.put(response_uri, response)
            return response_uri
        else:
            return
        
    def _is_display_document(self, document, app_res, spaces):
        # There are two conditions to decide if we should display a document.
        # 1. If it is in the DOC_TYPES_TO_DISPLAY list which lists the documents described in SID102.A and their data is available
        # 2. Or if it is a PDF attachment and it has been downloaded
        doc_id = document["sid004_doc_id"] 
        if document['sid004_doctype'] in ApplicationService.DOC_TYPES_TO_DISPLAY:
            doc_type = document['sid004_doctype']
            if doc_type == adaptor.DOC_TYPE_RESPONSIBLE_AUTHORITY_REF_NUM:
                # check the responsible authority reference number data exists
                cond1 = app_res.has_var('sid072a_dict')
            elif doc_type == adaptor.DOC_TYPE_ACCEPT_REJECT:
                # check the accept reject data exists
                cond1 = doc_id in app_res.sid005a_dict_dict
            elif doc_type == adaptor.DOC_TYPE_APPLICATION_FOR_PLANNING_PERMIT:
                # check the application data exists
                cond1 = app_res.has_var('application')
            elif doc_type == adaptor.DOC_TYPE_REFERRAL_REQUEST:
                # check the referral data exists
                cond1 = app_res.has_var('sid061a_dict_dict') and doc_id in app_res.sid061a_dict_dict
            else:
                cond1 = False
        else:
            cond1 = False
        cond2a = doc_id in app_res.sid005a_dict_dict
        try:
            # check it is a PDF
            cond2b = app_res.sid005a_dict_dict[doc_id]["sid005a_current_document_format"] == "PDF"
        except:
            # if we fail to get this evaluate this condition. It is most likely one of the pieces of data is missing
            # e.g the doc id or the doc format. Hence we will default to False
            cond2b = False
        cond2c = spaces.exists(Uri('spear:app-attachment/%s' % doc_id))             
        return cond1 or (cond2a and cond2b and cond2c)